package com.kongjs.common.core.context;

import java.lang.reflect.Constructor;

public class ContextHolder {
    public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";
    public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";
    public static final String MODE_GLOBAL = "MODE_GLOBAL";
    private static final String MODE_PRE_INITIALIZED = "MODE_PRE_INITIALIZED";
    public static final String SYSTEM_PROPERTY = "scp.core.strategy";
    private static String strategyName = System.getProperty(SYSTEM_PROPERTY);
    private static ContextHolderStrategy strategy;
    private static int initializeCount = 0;

    private static void initialize() {
        initializeStrategy();
        ++initializeCount;
    }

    static {
        initialize();
    }

    private static void initializeStrategy() {
        if (MODE_PRE_INITIALIZED.equals(strategyName)) {
            //Assert.state(strategy != null, "When using MODE_PRE_INITIALIZED, setContextHolderStrategy must be called with the fully constructed strategy");
        } else {
            if (strategyName == null || strategyName.isEmpty()) {
                strategyName = MODE_THREADLOCAL;
            }
            if (strategyName.equals(MODE_THREADLOCAL)) {
                strategy = new ThreadLocalContextHolderStrategy();
            } else if (strategyName.equals(MODE_INHERITABLETHREADLOCAL)) {
                strategy = new InheritableThreadLocalContextHolderStrategy();
            } else if (strategyName.equals(MODE_GLOBAL)) {
                strategy = new GlobalContextHolderStrategy();
            }
        }
    }

    public static int getInitializeCount() {
        return initializeCount;
    }

    public static void setStrategyName(String strategyName) {
        ContextHolder.strategyName = strategyName;
        initialize();
    }

    public static ContextHolderStrategy getContextHolderStrategy() {
        return strategy;
    }

    public static void setContextHolderStrategy(ContextHolderStrategy strategy) {
        //Assert.notNull(strategy, "securityContextHolderStrategy cannot be null");
        strategyName = MODE_PRE_INITIALIZED;
        ContextHolder.strategy = strategy;
        initialize();
    }

    public static void clearContext() {
        strategy.clearContext();
    }

    public static Context getContext() {
        return strategy.getContext();
    }

    public static void setContext(Context context) {
        strategy.setContext(context);
    }
}
